require(plotly) #carregue pacote

competition = function(data,coef,NArm=TRUE, graphic=TRUE, table=TRUE){ #funo
if (NArm==TRUE){ #se o usurio quer remover os NAs
  data.na = na.omit(data)  ##remove todos os NAs com na.omit 
  na = as.numeric(dim(data)[1] - dim(data.na)[1]) #contabiliza os NAs
  cat(na,"registros NA's foram removidos","\n") #mensagem para o usurio
  data = data.na #padronizando o nome do objeto
  
    } else { #condio alternativa: se o usurio no quiser que os NAs sejam removidos
    data = data #renomeia dataframe
  }
  
###Teste de premissas: conferindo se as entradas esto corretas
#1.conferir dataframe "data"
if (class(data) != "data.frame"){ #se a classe do objeto  diferente de dataframe:
  stop("O objeto data no  um dataframe")} #pare e exiba uma mensagem

if (ncol(data) != 5){ #se o objeto no tem 5 colunas
  stop("O objeto data deve ter 5 colunas")} #pare e exiba uma mensagem
  
#2.conferir matriz "coef"
if (class(coef)!= "matrix"){ #se a classe do objeto  diferente de matriz:
stop("O objeto coef no  uma matriz")} #pare e exiba uma mensagem

if (dim(coef)[1]!=dim(coef)[2]){ #Se o n de linhas ou colunas  diferente do nmero de colunas
  stop("O objeto coef no apresenta a dimenso correta")}  #pare e exiba uma mensagem

sum = sum(rownames(coef)[] != colnames(coef)[]) ##somar ocorrncias de nome de spp. diferentes entre linhas e colunas
if (sum > 0){
    stop("O nome das espcies no  igual para linhas e colunas da matriz")}  #pare e exiba uma mensagem

#Manipulao dos dados
#padronizando nome de linhas e colunas do objeto data
colnames(data) = c("individuals", "species","u","x","y")

#Criar a estrutura da matriz de distancia para todos os pares de indivduos da comunidade
nrow.data= dim(data)[1] #objeto indicando o tamanho que a matriz ter (total de ind. na comunidade)
dist=matrix(NA,nrow = nrow.data,ncol = nrow.data) #estrutura da matriz
diag(dist)=0 #colocando zeros na diagonal principal
rownames(dist) = seq(1,nrow.data) #nomeia as linhas com o rtulo dos indivduos
colnames(dist) = seq(1,nrow.data) #nomeia as colunas com o rtulo dos indivduos

#Calcular distncia
#Calculada com base no Teorema de Pitagras (distncia = raiz da soma dos quadrado dos catetos)
i=1
for (i in 1:(nrow.data-1)){ #cria um contador para para cada indivduo i (colunas da matriz)
    j = i+1 #para cada indivduo pegue o indivduo j da posio posterior
    for (j in j:nrow.data){ #para cada par de indivduos ij calcule:
      dx2 = (data$x[j]-data$x[i])^2 #quadrado do deltax entre ij
      dy2 = (data$y[j]-data$y[i])^2 #quadrado do delta y entre ij
      dist[i,j] = sqrt(dx2 + dy2) #raiz da soma dos quadrados  colocada na posio ij da matriz
      dist[j,i] = sqrt(dx2 + dy2) #raiz da soma dos quadrados  colocada na posio ji da matriz
    }
    }
    
#Atribuir uma identificao nica (rtulo) para cada espcie da comunidade
#Essa identificao nica ser necessria para o prximo passo, quando eu for manipular a matriz com a escala espacial de efeito das espcies
spp.name=sort(unique(data$species)) #vetor com nome das spp ordenado
spp.number= seq(from=1,to=length(spp.name),1) #cria vetor com a sequncia de nmeros que serviro como cdigo das espcie (caso o usurio esteja usando variveis do tipo string para os nomes. Nmero de cdigos = nmero de spp.)
abund=as.numeric(table(data$species)) #extrai vetor de abundancias das spp (em ordem alfabetica, assim como os cdigos)
id=data.frame(spp.name,spp.number,abund) ##criando um objeto unindo as informaes (nome, cdigo e abundncia por spp.)

#criar nova coluna no conjunto de dados atribuindo os rtulos espcie-especficos a cada indivduo
data$id.spp=rep(NA,nrow.data) #estrutura da coluna
i=1 #inicia o contador de espcies em 1
for (i in 1:length(id$spp.name)){ #estabelece a condio para o loop: enquanto i for menor ou igual ao nmero de spp., faa:
  x = which(data$species==id$spp.name[i]) #extrai a posio de cada spp.i em funo do seu nome
  data$id.spp[x] = id$spp.number[i] #coloca o cdigo da espcie i em todas as posies onde ela ocorre
    i=i+1 #incrementa o contador em 1 para continuar o loop
  } 
  
#Para facilitar a manipulao e os clculos intermedirios at chegar ao Wij, preciso que as matrizes de distancia (dist) e de escala de efeito (coef) tenham a mesma dimenso
#a matriz de escala de efeito est entre pares de especies
#a matriz de distncias est entre pares de individuos
#Assim vou manipular os objetos para obter uma matriz coef que mostre os valores da escala espacial de efeito por indivduo (de acordo com a spp a qual pertencem). Ou seja, indivduos da mesma espcie recebero o mesmo valor.

#Substituir nome das spp. pelos cdigos numricos nas linhas e colunas da matriz por espcie
i=1 #criando contador de spp.
for (i in 1:length(id$spp.name)){ #Para cada spp i do nmero total de spp:
spp = id$spp.name[i] #extrai o nome da espcie i
number = id[spp.name==spp,2] #extrai o cdigo que corresponde a spp. i
x = which(colnames(coef)==spp) #extrai a posio da spp. i no nome das colunas da matriz
colnames(coef)[x]=number ##substitui o nome pelo cdigo
i=i+1 #incrementa o contador em 1 para continuar o loop
}

rownames(coef)=colnames(coef) #igualando o nome das linhas e colunas da matriz

coef.ind = matrix(NA,nrow = nrow.data,ncol = nrow.data)  #criar a estrutura da matriz por indivduo
rownames(coef.ind) = data$id.spp #renomeando os indivduos nas linhas de acordo com o cdigo das especies na ordem em que aparecem nos dados
colnames(coef.ind) = data$id.spp #renomeando os indivduos nas colunas


#Cada linha da matriz representa a escala espacial de efeito de uma espcie (m) sobre cada espcie j (colunas)
#Assim, vou repetir os coef.da matriz de especies para a matriz  de individuos repetindo os valores das escalas de efeito espcie-especficos para cada par de individuo, de acordo com a identidade deles
m=1 #iniciando o contador de espcies
for (m in 1:dim(coef)[1]){ #condio que determina a parada do loop para as espcies que exercem o efeito (linhas)
    j=m #contador para espcies j que recebem o efeito da spp. m
    for (j in 1:dim(coef)[2]){ #condio que determina a parada do loop para as espcies que recebem o efeito
      mj = coef[rownames(coef)==m,colnames(coef)==j] #extrai o coefiente de interaao das spp. mj
      coef.ind[rownames(coef.ind)==m,colnames(coef.ind)==j] = mj #atribui o valor do coefiente para todos os pares de individuos mj na matriz por indivduo
      j=j+1 #incrementa o contador para voltar para o loop
      }
  }

#Iniciando o clculo do W (efeito de vizinhana em funo da identidade, tamanho e distncia dos vizinhos)
#Etapa1: calcular Wijkm (efeito de cada indivduo k da spp.m sobre cada vizinho i da spp. j)
#Wijkm = tamanho.km*e^(-escalajm*dijkm)
#Antes disso  necessrio Voltar os nomes das linhas e das colunas dos trs objetos envolvidos no clculo (u,dist,coef.ind) para a identificao por indivduos (Sequncia numrica)
u = data$u #criar vetor tamanho
names(u) = seq(1,length(u)) #renomear vetor tamanho
rownames(coef.ind) = seq(1,nrow.data) #renomear linhas da matriz
colnames(coef.ind) = seq(1,nrow.data) #renomear colunas da matriz
rownames(dist) #OK, padronizado
colnames(dist) #OK, padronizado

matrix.wijkm=matrix(NA,nrow = nrow.data,ncol = nrow.data) #estrutura da matriz
rownames(matrix.wijkm) = seq(1,nrow.data) #renomear linhas da matriz
colnames(matrix.wijkm) = seq(1,nrow.data) #renomear colunas da matriz

i=1 #inicia o contador para cada individuo i que recebe o efeito
for (i in 1:nrow.data){ #para cada individuo focal i:
  k=1 #crie um k correspondendo a cada vizinho de i
  for (k in 1:nrow.data){ #para cada vizinho k calcule
    wik = u[k]*exp(-(coef.ind[k,i])*dist[k,i]) #valor do efeito de k sobre i
    matrix.wijkm[k,i] = wik #guarda na linha k coluna i da matriz
    k=k+1 #incrementa o contador para voltar para o loop
    }
}

diag(matrix.wijkm)=0 #diagonal = efeito de cada individuo sobre si = 0

#Etapa2:calcular Wijm (efeitos de cada especie m sobre o individuo i da especie j)
#Wijm = soma do efeito de todos os indivduos k da espcie m sobre indivduo i da espcie j
wijm = matrix(NA,nrow = dim(coef)[1],ncol=nrow.data) #estrutura da matriz
rownames(wijm) = seq(1,dim(coef)[1]) #nomeando as linhas
colnames(wijm) = seq(1,nrow.data) #nomeando as linhas

#trocando a identificao de indivduos para espcies na matriz Wijkm (para que eu possa somar as linhas dos indivduos da mesma spp)
rownames(matrix.wijkm) = data$id.spp

#Somando os valores dos indivduos da mesma spp.
i=1 #iniciando contador de indivduos
for (i in 1:nrow.data){ #para cada indivduo i (colunas):
  m=1 #crie um m para espcie que faz o efeito (linhas)
  for (m in 1:dim(coef)[1]){ #para cada espcie:
  wijm[m,i]=sum(matrix.wijkm[which(rownames(matrix.wijkm)==m),i]) #some os valores do efeito de todos os indivduos da mesma spp. e guarde na linha m da coluna i
  m+1 #incrementa o contador para voltar para o loop
  }  
  }

#E,finalmente, calcular o Wij (efeito total de vizinhana sobre o indivduo i)
#Wij = soma dos efeitos de todas as espcies sobre o indivduo i
wij = round(apply(wijm,2,sum),4) #soma de cada uma das colunas com 4 casas decimais
index.wij = data.frame(seq(1:nrow.data),wij)#acrescentando uma coluna com o cdigo dos indivduos
colnames(index.wij) = c("Individuals","Wij") #renomeando colunas


#Fazendo o grfico
if (graphic==TRUE){ #se o usurio quer o grfico:
  data.graph = cbind(data,index.wij$Wij) #concatene informaes necessrias
  colnames(data.graph) = c("Indivduo","Spp.","Tamanho","CoordenadaX","CoordenadaY","Id_Spp.","Wij") #renomeie as colunas para o eixo do grfico
graphic = plot_ly(data.graph, x=~CoordenadaX, y = ~CoordenadaY, type="scatter", mode = "markers", color = ~Wij, size = ~Wij,colors="YlOrRd") #faa o grfico
print(graphic)
} 

#Salvando ou no o arquivo no diretrio do usurio, de acordo com a escolha do usurio
if (table == TRUE){ #se o usurio quer o arquivo salvo:
write.table(index.wij,file="Wij.txt",sep = "\t",row.names = FALSE) #exporte o arquivo em .txt para o diretrio de trabalho
}

return(index.wij)
}


#########################################################